home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Tool Chest / Development Tools & Languages / Macintosh Common Lisp Related / interfaces / AOCE folder / DigitalSignature.lisp < prev    next >
Encoding:
Text File  |  1994-09-12  |  18.2 KB  |  421 lines  |  [TEXT/CCL2]

  1.  
  2. (in-package :TRAPS)             ; ***********************************************************
  3. ; Created: Sunday, February 7, 1993 at 4:54PM
  4. ;  DigitalSignature.p
  5. ;  Pascal Interface to the Macintosh Libraries
  6. ;     ••• Apple Confidential •••
  7. ;     ••• Provided with AOCE Beta seed under license agreement with   •••
  8. ;     ••• Apple Computer, Inc.  Use for any purpose other than        •••
  9. ;     ••• development of AOCE-based Macintosh products is a violation •••
  10. ;     ••• of the license agreement.                                   •••
  11. ;   Copyright Apple Computer, Inc. 1990-1993
  12. ;   All rights reserved
  13. ; ***********************************************************
  14.  
  15. ; $IFC UNDEFINED UsingIncludes
  16. ; $SETC UsingIncludes:= 0
  17. ; $ENDC
  18.  
  19. ; $IFC NOT UsingIncludes
  20.  
  21. ; $ENDC
  22.  
  23. ; $IFC UNDEFINED UsingDigitalSignature
  24. ; $SETC UsingDigitalSignature:= 1
  25.  
  26. ; $I+
  27. ; $SETC DigitalSignatureIncludes:= UsingIncludes
  28. ; $SETC UsingIncludes:= 1
  29.  
  30. ; $IFC UNDEFINED UsingFiles
  31.  
  32. (require-interface 'FILES)      ; $I $$Shell(PInterfaces)Files.p
  33. ; $ENDC
  34.  
  35. ; $IFC UNDEFINED UsingMemory
  36.  
  37. (require-interface 'MEMORY)     ; $I $$Shell(PInterfaces)Memory.p
  38. ; $ENDC
  39.  
  40. ; $IFC UNDEFINED UsingTypes
  41.  
  42. (require-interface 'TYPES)      ; $I $$Shell(PInterfaces)Types.p
  43. ; $ENDC
  44.  
  45. ; $SETC UsingIncludes:= DigitalSignatureIncludes
  46.  
  47. ;  —————————————————————————— TRAP SELECTORS —————————————————————————— 
  48.  
  49. (defconstant $kSIGNewContext 1900)
  50. (defconstant $kSIGDisposeContext 1901)
  51.  
  52. (defconstant $kSIGSignPrepare 1902)
  53. (defconstant $kSIGSign 1903)
  54.  
  55. (defconstant $kSIGVerifyPrepare 1904)
  56. (defconstant $kSIGVerify 1905)
  57.  
  58. (defconstant $kSIGDigestPrepare 1906)
  59. (defconstant $kSIGDigest 1907)
  60.  
  61. (defconstant $kSIGProcessData 1908)
  62.  
  63. (defconstant $kSIGShowSigner 1909)
  64. (defconstant $kSIGGetSignerInfo 1910)
  65. (defconstant $kSIGGetCertInfo 1911)
  66. (defconstant $kSIGGetCertNameAttributes 1912)
  67. (defconstant $kSIGGetCertIssuerNameAttributes 1913)
  68.  
  69. (defconstant $kSIGFileIsSigned 2500)
  70. (defconstant $kSIGSignFile 2501)
  71. (defconstant $kSIGVerifyFile 2502)
  72.  
  73. ;  values of SIGNameAttributeType 
  74. (defconstant $kSIGCountryCode 0)
  75. (defconstant $kSIGOrganization 1)
  76. (defconstant $kSIGStreetAddress 2)
  77. (defconstant $kSIGState 3)
  78. (defconstant $kSIGLocality 4)
  79. (defconstant $kSIGCommonName 5)
  80. (defconstant $kSIGTitle 6)
  81. (defconstant $kSIGOrganizationUnit 7)
  82. (defconstant $kSIGPostalCode 8)
  83.  
  84. (def-mactype :SIGNAMEATTRIBUTETYPE (find-mactype :SIGNED-INTEGER))
  85.  
  86. ; Certificate status codes returned in SIGCertInfo or SIGSignerInfo from
  87. ; either SIGGetCertInfo or SIGGetSignerInfo respectively. kSIGValid means that
  88. ; the certificate is currently valid. kSIGPending means the certificate is
  89. ; currently not valid - but will be.  kSIGExpired means the certificate has
  90. ; expired. A time is always associated with a SIGCertStatus.  In each case the
  91. ; time has a specific interpretation.  When the status is kSIGValid the time is
  92. ; when the certificate will expire. When the status is kSIGPending the time is
  93. ; when the certificate will become valid. When the status is kSIGExpired the time
  94. ; is when the certificate expired. In the SIGCertInfo structure, the startDate
  95. ; and endDate fields hold the appropriate date information.  In the SIGSignerInfo
  96. ; structure, this information is provided in the certSetStatusTime field. In the
  97. ; SIGSignerInfo struct, the status time is actually represented by the SIGSignatureStatus
  98. ; field which can contain any of the types below. NOTE: The only time you will get
  99. ; a kSIGInvalid status is when it pertains to a SIGSignatureStatus field and only when
  100. ; you get a signature that was created after the certificates expiration date, something
  101. ; we are not allowing on the Mac but that may not be restricted on other platforms. Also,
  102. ; it will not be possible to get a kSIGPending value for SIGSignatureStatus on the Mac but
  103. ; possibly allowed by other platforms.
  104.  
  105. ;  Values for SIGCertStatus or SIGSignatureStatus 
  106.  
  107. (defconstant $kSIGValid 0)      ;  possible for either a SIGCertStatus or SIGSignatureStatus 
  108. (defconstant $kSIGPending 1)    ;  possible for either a SIGCertStatus or SIGSignatureStatus 
  109. (defconstant $kSIGExpired 2)    ;  possible for either a SIGCertStatus or SIGSignatureStatus 
  110. (defconstant $kSIGInvalid 3)    ;  possible only for a SIGSignatureStatus 
  111.  
  112. (def-mactype :SIGCERTSTATUS (find-mactype :SIGNED-INTEGER))
  113. (def-mactype :SIGSIGNATURESTATUS (find-mactype :SIGNED-INTEGER))
  114.  
  115. ;  Gestalt selector code - returns toolbox version in low-order word 
  116.  
  117. (defconstant $gestaltDigitalSignatureVersion :|dsig|)
  118.  
  119. ;  Number of bytes needed for a digest record when using SIGDigest 
  120. (defconstant $kSIGDigestSize 16)
  121.  
  122. (def-mactype :SIGDIGESTDATA (find-mactype :ARRAY))
  123. (def-mactype :SIGDIGESTDATAPTR (find-mactype :POINTER))
  124.  
  125. (defrecord SIGCertInfo 
  126.    (startDate :SIGNED-LONG)     ;  cert start validity date 
  127.    (endDate :SIGNED-LONG)       ;  cert end validity date 
  128.    (certStatus :SIGNED-INTEGER) ;  see comment on SIGCertStatus for definition 
  129.    (certAttributeCount :SIGNED-LONG);  number of name attributes in this cert 
  130.    (issuerAttributeCount :SIGNED-LONG);  number of name attributes in this certs issuer 
  131.    (serialNumber (:STRING 255)) ;  cert serial number 
  132.    )
  133.  
  134. (def-mactype :SIGCERTINFOPTR (find-mactype :POINTER))
  135.  
  136. (defrecord SIGSignerInfo 
  137.    (signingTime :SIGNED-LONG)   ;  time of signing 
  138.    (certCount :SIGNED-LONG)     ;  number of certificates in the cert set 
  139.    (certSetStatusTime :SIGNED-LONG);  Worst cert status time. See comment on
  140. ;                                             SIGCertStatus for definition 
  141.    (signatureStatus :SIGNED-INTEGER);  The status of the signature. See comment on
  142. ;                                             SIGCertStatus for definition
  143.    )
  144.  
  145. (def-mactype :SIGSIGNERINFOPTR (find-mactype :POINTER))
  146.  
  147. (defrecord SIGNameAttributesInfo 
  148.    (onNewLevel :BOOLEAN)
  149.    (attributeType :SIGNED-INTEGER)
  150.    (attributeScript :SIGNED-INTEGER)
  151.    (attribute (:STRING 255))
  152.    )
  153.  
  154. (def-mactype :SIGNAMEATTRIBUTESINFOPTR (find-mactype :POINTER))
  155.  
  156. (def-mactype :SIGCONTEXTPTR (find-mactype :POINTER))
  157. (def-mactype :SIGSIGNATUREPTR (find-mactype :POINTER))
  158.  
  159. ; Certificates are always in order. That is, the signers cert is always 0, the
  160. ; issuer of the signers cert is always 1 etc… to the number of certificates-1.
  161. ; You can use this constant for readability in your code.
  162.  
  163. (defconstant $kSIGSignerCertIndex 0)
  164.  
  165. ; Call back procedure supplied by developer, return false to cancel the current process.
  166.  
  167. (def-mactype :SIGSTATUSPROCPTR (find-mactype :POINTER));  FUNCTION SIGStatusProcPtr(): BOOLEAN;
  168.  
  169. ; Resource id of standard signature icon suite, all sizes and colors are available.
  170.  
  171. (defconstant $kSIGSignatureIconResID -16797)    ; Note that this is the FINAL value for this constant, not the BETA value!
  172.  
  173. ;  ——————————————————————————————— CONTEXT CALLS ——————————————————————————————— 
  174. ; To use the Digital Signature toolbox you will need a SIGContextPtr.  To create
  175. ; a SIGContextPtr you simply call SIGNewContext and it will create and initialize
  176. ; a context for you.  To free the memory occupied by the context and invalidate
  177. ; its internal data, call SIGDisposeContext. An initialized context has no notion
  178. ; of the type of operation it will be performing however, once you call
  179. ; SIGSignPrepare SIGVerifyPrepare, or SIGDigestPrepare, the contexts operation
  180. ; type is set and to switch  to another type of operation will require creating a
  181. ; new context. Be sure to pass the same context to corresponding toolbox calls
  182. ; (ie: SIGSignPrepare; SIGProcessData, SIGSign)  in other words mixing lets say
  183. ; signing and verify calls with the same context is not allowed.
  184.  
  185.  
  186. (deftrap _signewcontext ((context (:pointer :pointer)))
  187.    (:stack :signed-integer)
  188.    (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1900) context))
  189.  
  190.  
  191. (deftrap _sigdisposecontext ((context :pointer))
  192.    (:stack :signed-integer)
  193.    (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1901) context))
  194.  
  195. ;  ——————————————————————————————— SIGNING CALLS ——————————————————————————————— 
  196. ; Once you have created a SIGContextPtr, you create a signature by calling
  197. ; SIGSignPrepare once, followed by n calls to SIGProcessData, followed by one call
  198. ; to SIGSign. To create another signature on different data but for the same
  199. ; signer, don't dispose of the context and call SIGProcessData for the new data
  200. ; followed by a call SIGSign again. In this case the signer will not be prompted
  201. ; for their signer and password again as it was already provided.  Once you call
  202. ; SIGDisposeContext, all signer information will be cleared out of the context and
  203. ; the signer will be re-prompted.  The signer file FSSpecPtr should be set to nil
  204. ; if you want the toolbox to use the last signer by default or prompt for a signer
  205. ; if none exists.  The prompt parameter can be used to pass a string to be displayed
  206. ; in the dialog that prompts the user for their password.  If the substring "^1"
  207. ; (without the quotes) is in the prompt string, then the toolbox will replace it
  208. ; with the name of the signer from the signer selected by the user.  If an empty
  209. ; string is passed, the following default string will be sent to the toolbox
  210. ; "\pSigning as ^1.".  You can call any of the utility routines after SIGSignPrepare
  211. ; or SIGSign to get information about the signer or certs.
  212.  
  213.  
  214. (deftrap _sigsignprepare ((context :pointer) (signerfile (:pointer :fsspec)) (prompt (:pointer (:string 255))) (signaturesize (:pointer :signed-long)))
  215.    (:stack :signed-integer)
  216.    (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1902) context signerfile prompt signaturesize))
  217.  
  218.  
  219. (deftrap _sigsign ((context :pointer) (signature :pointer) (statusproc :pointer))
  220.    (:stack :signed-integer)
  221.    (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1903) context signature statusproc))
  222.  
  223. ;  ——————————————————————————————— VERIFYING CALLS ——————————————————————————————— 
  224. ; Once you have created a SIGContextPtr, you verify a signature by calling
  225. ; SIGVerifyPrepare  once, followed by n calls to SIGProcessData, followed by one
  226. ; call to SIGVerify. Check the return code from SIGVerify to see if the signature
  227. ; verified or not (noErr is returned on  success otherwise the appropriate error
  228. ; code).  Upon successfull verification, you can call any of the utility routines
  229. ; to find out who signed the data.
  230.  
  231.  
  232. (deftrap _sigverifyprepare ((context :pointer) (signature :pointer) (signaturesize :signed-long) (statusproc :pointer))
  233.    (:stack :signed-integer)
  234.    (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1904) context signature signaturesize statusproc))
  235.  
  236.  
  237. (deftrap _sigverify ((context :pointer))
  238.    (:stack :signed-integer)
  239.    (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1905) context))
  240.  
  241. ;  —————————————————————————————— DIGESTING CALLS —————————————————————————————— 
  242. ; Once you have created a SIGContextPtr, you create a digest by calling
  243. ; SIGDigestPrepare once, followed by n calls to SIGProcessData, followed by one
  244. ; call to SIGDigest.  You can dispose of the context after SIGDigest as the
  245. ; SIGDigestData does not reference back into it.  SIGDigest returns the digest in
  246. ; digest.
  247.  
  248.  
  249. (deftrap _sigdigestprepare ((context :pointer))
  250.    (:stack :signed-integer)
  251.    (:stack-trap #xAA5D :d0 (+ (ash 2 16) 1906) context))
  252.  
  253.  
  254. (deftrap _sigdigest ((context :pointer) (digest (:array :unsigned-byte (- \#$KSIGDIGESTSIZE 1 -1))))
  255.    (:stack :signed-integer)
  256.    (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1907) context digest))
  257.  
  258. ;  —————————————————————————————— PROCESSING DATA —————————————————————————————— 
  259. ; To process data during a digest, sign, or verify operation call SIGProcessData
  260. ; as many times as necessary and with any sized blocks of data.  The data needs to
  261. ; be processed in the same order during corresponding sign and verify operations
  262. ; but does not need to be processed in the same sized chunks (i.e., the toolbox
  263. ; just sees it as a continuous bit stream).
  264.  
  265.  
  266. (deftrap _sigprocessdata ((context :pointer) (data :pointer) (datasize :signed-long))
  267.    (:stack :signed-integer)
  268.    (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1908) context data datasize))
  269.  
  270. ;  ——————————————————————————————— UTILITY CALLS ——————————————————————————————— 
  271. ; Given a context that has successfully performed a verification SIGShowSigner
  272. ; will  display a modal dialog with the entire distinguished name of the person
  273. ; who signed the data. the prompt (if supplied) will appear at the top of the
  274. ; dialog.  If no prompt is specified, the default prompt "\pVerification
  275. ; Successfull." will appear.
  276. ; Given a context that has been populated by calling SIGSignPrepare, SIGSign or a
  277. ; successful SIGVerify, you can make the remaining utility calls:
  278. ; SIGGetSignerInfo will return the SignerInfo record.  The certCount can be used
  279. ; to index into the certificate set when calling SIGGetCertInfo,
  280. ; SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes. The signingTime is
  281. ; only defined if the call is made after SIGSign  or SIGVerify. The certSetStatus
  282. ; will tell you the best status of the entire certificate set while
  283. ; certSetStatusTime will correspond to the time associated with that status (see
  284. ; definitions above).
  285. ; SIGGetCertInfo will return the SIGCertInfo record when given a valid index into
  286. ; the cert set in  certIndex.  Note: The cert at index kSIGSignerCertIndex is
  287. ; always the signers certificate.  The  serial number, start date and end date
  288. ; are there should you wish to display that info.  The  certAttributeCount and
  289. ; issuerAttributeCount provide the number of parts in the name of that certificate
  290. ; or that certificates issuer respectively.  You use these numbers to index into
  291. ; either SIGGetCertNameAttributes or SIGGetCertIssuerNameAttributes to retrieve
  292. ; the name. The certStatus will tell you the status of the certificate while
  293. ; certStatusTime will correspond to the time associated with that status (see
  294. ; definitions above).
  295. ; SIGGetCertNameAttributes and SIGGetCertIssuerNameAttributes return name parts
  296. ; of the certificate at  certIndex and attributeIndex.  The newLevel return value
  297. ; tells you wether the name attribute returned is at the same level in the name
  298. ; hierarchy as the previous attribute.  The type return value tells you  the type
  299. ; of attribute returned. nameAttribute is the actual string containing the name
  300. ; attribute.   So, if you wanted to display the entire distinguished name of the
  301. ; person who's signature was just validated you could do something like this;
  302. ;     (…… variable declarations and verification code would preceed this sample ……)
  303. ;     error = SIGGetCertInfo(verifyContext, kSIGSignerCertIndex, &certInfo);
  304. ;     HandleErr(error);
  305. ;     for (i = 0; i <= certInfo.certAttributeCount-1; i++)
  306. ;         error = SIGGetCertNameAttributes(verifyContext, kSIGSignerCertIndex, i, &newLevel, &type, theAttribute);
  307. ;         HandleErr(error);
  308. ;         DisplayNamePart(theAttribute, type, newLevel);
  309.  
  310.  
  311. (deftrap _sigshowsigner ((context :pointer) (prompt (:pointer (:string 255))))
  312.    (:stack :signed-integer)
  313.    (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1909) context prompt))
  314.  
  315.  
  316. (deftrap _siggetsignerinfo ((context :pointer) (signerinfo (:pointer :sigsignerinfo)))
  317.    (:stack :signed-integer)
  318.    (:stack-trap #xAA5D :d0 (+ (ash 4 16) 1910) context signerinfo))
  319.  
  320.  
  321. (deftrap _siggetcertinfo ((context :pointer) (certindex :signed-long) (certinfo (:pointer :sigcertinfo)))
  322.    (:stack :signed-integer)
  323.    (:stack-trap #xAA5D :d0 (+ (ash 6 16) 1911) context certindex certinfo))
  324.  
  325.  
  326. (deftrap _siggetcertnameattributes ((context :pointer) (certindex :signed-long) (attributeindex :signed-long) (attributeinfo (:pointer :signameattributesinfo)))
  327.    (:stack :signed-integer)
  328.    (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1912) context certindex attributeindex attributeinfo))
  329.  
  330.  
  331. (deftrap _siggetcertissuernameattributes ((context :pointer) (certindex :signed-long) (attributeindex :signed-long) (attributeinfo (:pointer :signameattributesinfo)))
  332.    (:stack :signed-integer)
  333.    (:stack-trap #xAA5D :d0 (+ (ash 8 16) 1913) context certindex attributeindex attributeinfo))
  334.  
  335. ;  ——————————————————————————— FILE SIGN & VERIFY CALLS —————————————————————————— 
  336. ; These calls allow you to detect the presence of a standard signtaure in a file as
  337. ; well as sign and verify files in a standard way.  An example of this is the Finder,
  338. ; which uses these calls to allow the user to "drop sign" a file.
  339. ; To detect if a file is signed in the standard way, pass the FSSpec of the file to SIGFileIsSigned.
  340. ; A result of noErr means the file is in fact signed, otherwise, a kSIGNoSignature error will
  341. ; be returned.
  342. ; Once you have created a SIGContextPtr, you can make calls to either sign or verify a file in
  343. ; a standard way:
  344. ; To sign a file, call SIGSignPrepare followed by 'n' number of calls to SIGSignFile,
  345. ; passing it the file spec for each file you wish to sign in turn.  You supply the context, the signature
  346. ; size that was returned from SIGSignPrepare and an optional call back proc.  The call will take care of all
  347. ; the processing of data and affixing the signature to the file. If a signature already exists in the file,
  348. ; it is replaced with the newly created signature.
  349. ; To verify a file that was signed using SIGSignFile, call SIGVerifyFile passing it a new context and
  350. ; the file spec.  Once this call has completed, if the verification is successfull, you can pass the context
  351. ; to SIGShowSigner to display the name of the person who signed the file.
  352.  
  353.  
  354. (deftrap _sigfileissigned ((filespec :fsspec))
  355.    (:stack :signed-integer)
  356.    (:stack-trap #xAA5D :d0 (+ (ash 2 16) 2500) filespec))
  357.  
  358.  
  359. (deftrap _sigsignfile ((context :pointer) (signaturesize :signed-long) (filespec :fsspec) (statusproc :pointer))
  360.    (:stack :signed-integer)
  361.    (:stack-trap #xAA5D :d0 (+ (ash 8 16) 2501) context signaturesize filespec statusproc))
  362.  
  363.  
  364. (deftrap _sigverifyfile ((context :pointer) (filespec :fsspec) (statusproc :pointer))
  365.    (:stack :signed-integer)
  366.    (:stack-trap #xAA5D :d0 (+ (ash 6 16) 2502) context filespec statusproc))
  367.  
  368. ; $ENDC                         ;  UsingDigitalSignature 
  369.  
  370. ; $IFC NOT UsingIncludes
  371.  
  372. ; $ENDC
  373.  
  374. (export '($KSIGSIGNATUREICONRESID $KSIGSIGNERCERTINDEX $KSIGDIGESTSIZE
  375.           $GESTALTDIGITALSIGNATUREVERSION $KSIGINVALID $KSIGEXPIRED
  376.           $KSIGPENDING $KSIGVALID $KSIGPOSTALCODE $KSIGORGANIZATIONUNIT
  377.           $KSIGTITLE $KSIGCOMMONNAME $KSIGLOCALITY $KSIGSTATE
  378.           $KSIGSTREETADDRESS $KSIGORGANIZATION $KSIGCOUNTRYCODE $KSIGVERIFYFILE
  379.           $KSIGSIGNFILE $KSIGFILEISSIGNED $KSIGGETCERTISSUERNAMEATTRIBUTES
  380.           $KSIGGETCERTNAMEATTRIBUTES $KSIGGETCERTINFO $KSIGGETSIGNERINFO
  381.           $KSIGSHOWSIGNER $KSIGPROCESSDATA $KSIGDIGEST $KSIGDIGESTPREPARE
  382.           $KSIGVERIFY $KSIGVERIFYPREPARE $KSIGSIGN $KSIGSIGNPREPARE
  383.           $KSIGDISPOSECONTEXT $KSIGNEWCONTEXT))
  384. (provide-interface 'DigitalSignature)